package com.zengdada.dml.service.impl;

import com.zengdada.authority.annotation.SysLog;
import com.zengdada.authority.annotation.SysLogType;
import com.zengdada.authority.utils.CommonUtils;
import com.zengdada.authority.utils.ExceptionUtil;
import com.zengdada.authority.utils.where.Where;
import com.zengdada.authority.utils.mapper.Page;
import com.zengdada.dml.model.DmlExtend;
import com.zengdada.dml.model.type.StaticSelect;
import com.zengdada.dml.service.PlatDmlAuthorityService;
import com.zengdada.dml.utils.DmlExecuteReturn;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.HashMap;

/**
 * @Auther: 12614
 * @Contact: 1261438511@qq.com
 * @Date: 2019-02-19 15:51
 * @Description:
 */
@Slf4j
@Service
public class PlatDmlAuthorityServiceImpl implements PlatDmlAuthorityService {

    @Autowired
    DataSource dataSource;
    @Autowired
    DmlPlatService dmlPlatService;
    @Autowired
    DmlExecutor dmlExecutor;

    @Override
    public DmlExecuteReturn query(String dmlId, HttpServletRequest request, Page page, String searchs, StaticSelect.SelectType selectType) {
        if (StringUtils.isBlank(dmlId)) {
            throw new RuntimeException("缺少参数:dmlId");
        }
        Where where = null;
        try {
            if (!StringUtils.isEmpty(searchs)) {
                where = Where.formJsonString(StringEscapeUtils.unescapeHtml4(searchs));
            }
        } catch (Exception e) {
            throw new RuntimeException("查询条件解析失败：" + e.getMessage());
        }
        try {
            DmlExtend dml = dmlPlatService.loadDml(dmlId);
            if (dml == null) {
                throw new RuntimeException(String.format("语句%s不存在", dmlId));
            }
            if (!(dml instanceof StaticSelect)) {
                throw new RuntimeException("该接口不允许执行此操作");
            }
            StaticSelect select = (StaticSelect) dml;
            if (selectType == null) {
                String type = request.getParameter("selectType");
                try {
                    selectType = CommonUtils.enumValueOf(StaticSelect.SelectType.class, new HashMap<String, Object>() {{
                        put("type", Integer.valueOf(type));
                    }});
                } catch (Exception e) {
                    //
                }
                selectType = selectType == null ? StaticSelect.SelectType.select : selectType;
            }
            select.setType(selectType.getType());
            try (Connection conn = dataSource.getConnection()) {
                DmlExecutor executor = dmlExecutor.init(request, conn);
                return executor.executeQuery(select, page, where, null);
            }
        } catch (Exception e) {
            if (log.isDebugEnabled()) {
                log.debug("dml查询执行失败：", e);
            }
            throw new RuntimeException(ExceptionUtil.getRawMessage(e));
        }
    }

    @Override
    @SysLog(value = "执行DML操作", type = SysLogType.SERVICE)
    public DmlExecuteReturn save(String dmlId, HttpServletRequest request) {
        if (StringUtils.isBlank(dmlId)) {
            throw new RuntimeException("缺少参数:dmlId");
        }
        try {
            DmlExtend dml = dmlPlatService.loadDml(dmlId);
            if (dml == null) {
                throw new RuntimeException(String.format("语句%s不存在", dmlId));
            }
            if (dml instanceof StaticSelect) {
                throw new RuntimeException("该接口不允许执行此操作");
            }
            try (Connection conn = dataSource.getConnection()) {
                DmlExecutor executor = dmlExecutor.init(request, conn);
                conn.setAutoCommit(false);
                try {
                    DmlExecuteReturn ret = executor.execute(dml);
                    conn.commit();
                    return ret;
                } catch (Exception e) {
                    conn.rollback();
                    throw new RuntimeException(String.format("保存失败:%s", ExceptionUtil.getRawMessage(e)));
                }
            }
        } catch (Exception e) {
            if (log.isDebugEnabled()) {
                log.debug("dml执行失败：", e);
            }
            throw new RuntimeException(ExceptionUtil.getRawMessage(e));
        }
    }
}
